package cn.cloud9.consumer.controller;

import cn.cloud9.consumer.configuration.feign.ProviderFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import cn.cloud9.consumer.pojo.Product;

import java.util.List;

@RestController
@RequestMapping("/consumer")
public class ConsumerController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @RequestMapping("/test")
    public String test() {
        return "from consumer message: hello!";
    }

    @Autowired
    private ProviderFeign providerFeign;

    private String serviceName = "cloud9-provider-service";

    /**
     * /consumer/find-all
     * @return
     */
    @RequestMapping("/find-all")
    public String findOrder() {

        // 获取服务列表
        List<String> services = discoveryClient.getServices();
        // 服务发现客户端对象 ，获取该名称下面的所以服务实例
        List<ServiceInstance> instances = discoveryClient.getInstances(serviceName);

        // 如果都是空的，则表示没有服务可以提供数据
        if ( CollectionUtils.isEmpty(services) || CollectionUtils.isEmpty(instances) ) return null;

        // 只获取第一个实例对象
        ServiceInstance instance = instances.get(0);

        // 得到主机名和端口
        String hostName = instance.getHost();
        int port = instance.getPort();

        // 拼接我们需要调用的接口地址
        String url = "http://" + hostName + ":" + port + "/product/all-list";


        // restTemplate 底层是httpClient实现，这里做了很多封装的处理， 我们只需要声明地址，请求方式，请求体信息，返回的结果类型即可， Product需要由消息的提供者声明
        ResponseEntity<List<Product>> responseEntity = restTemplate.exchange(url, HttpMethod.GET, null, new ParameterizedTypeReference<List<Product>>() {});


        return responseEntity.getBody().toString();
    }



    /**
     * /consumer/find-all-2
     * @return
     */
    @RequestMapping("/find-all-2")
    public String findOrderUseBalancer() {


        /**
         * 使用loadBalancer通过算法自动选择其中一个服务
         */
        ServiceInstance instance = loadBalancerClient.choose(serviceName);

        // 如果都是空的，则表示没有服务可以提供数据
        if (null == instance ) return null;

        // 得到主机名和端口
//        String hostName = instance.getHost();
//        int port = instance.getPort();

        // RestTemplate注解了@LoadBalanced, 这里可以不指明具体的IP地址端口号，只要写上服务名称也可以进行调用 拼接我们需要调用的接口地址
        String url = "http://" + serviceName + "/product/all-list";


        // restTemplate 底层是httpClient实现，这里做了很多封装的处理， 我们只需要声明地址，请求方式，请求体信息，返回的结果类型即可， Product需要由消息的提供者声明
        ResponseEntity<List<Product>> responseEntity = restTemplate.exchange(url, HttpMethod.GET, null, new ParameterizedTypeReference<List<Product>>() {});


        return responseEntity.getBody().toString();
    }


    @RequestMapping("/find-all-3")
    public String findOrderUseFeign() {
        List<Product> products = providerFeign.allList();
        return products.toString();
    }

}
